package com.lvbaoins.creditapp.controller;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.lvbaoins.creditapp.core.fastdfs.FastDFSClientComponent;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;


/**
 * @ClassName: FastDfsFileController.java
 * @Description: fastdfs分布式文件管理controller
 * @version: v1.0.0
 * @author: liwei
 * @date: 2019年7月10日 上午10:08:55
 */
@Api(value = "图片管理",tags = "图片管理")
@Controller
@RequestMapping("/file")
@Slf4j
public class FastDfsFileController {

    @Autowired
    private FastDFSClientComponent fastDFSClientComponent;


    /**
     * 路径分隔符
     */
    public static final String SEPARATOR = "/";
    /**
     * Point
     */
    public static final String POINT = ".";

    public static Map<String, String> EXT_MAPS = new HashMap<String, String>();
    static  {
        // image
        EXT_MAPS.put("png", "image/png");
        EXT_MAPS.put("gif", "image/gif");
        EXT_MAPS.put("bmp", "image/bmp");
        EXT_MAPS.put("ico", "image/x-ico");
        EXT_MAPS.put("jpeg", "image/jpeg");
        EXT_MAPS.put("jpg", "image/jpeg");
        // 压缩文件
        EXT_MAPS.put("zip", "application/zip");
        EXT_MAPS.put("rar", "application/x-rar");
        // doc
        EXT_MAPS.put("pdf", "application/pdf");
        EXT_MAPS.put("ppt", "application/vnd.ms-powerpoint");
        EXT_MAPS.put("xls", "application/vnd.ms-excel");
        EXT_MAPS.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        EXT_MAPS.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
        EXT_MAPS.put("doc", "application/msword");
        EXT_MAPS.put("doc", "application/wps-office.doc");
        EXT_MAPS.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        EXT_MAPS.put("txt", "text/plain");
        // 音频
        EXT_MAPS.put("mp4", "video/mp4");
        EXT_MAPS.put("flv", "video/x-flv");
    }


    /**
     * 以附件形式下载文件
     *
     * @param filePath 文件地址
     * @param response
     */
    @GetMapping("/download/file")
    public void downloadFile(@RequestParam String filePath, HttpServletResponse response) throws IOException {
        try {
            if(StringUtils.isNoneBlank(filePath)){
                byte[] fileByte = fastDFSClientComponent.download(filePath);

                if (filePath != null) {

                    // 设置响应头
                    // 文件编码 处理文件名中的 '+'、' ' 特殊字符
                    String fileName = IdUtil.simpleUUID() + filePath.substring(filePath.lastIndexOf("."));
                    response.setHeader("Content-Disposition", "attachment;filename=" + new String( fileName.getBytes("UTF-8"), "ISO8859-1" ));
                    response.setContentType(this.EXT_MAPS.get(filePath.substring(filePath.lastIndexOf("/") + 1)) + ";charset=UTF-8");
                    response.setHeader("Accept-Ranges", "bytes");
                    response.setHeader("Set-Cookie", "fileDownload=true; path=/");
                }
                IOUtils.write(fileByte, response.getOutputStream());
            }

        } catch (Exception e) {
            log.info("下载失败！-->" + e);
            response.setHeader("Set-Cookie", "fileDownload=false; path=/");
            JSONObject json =new JSONObject();
            json.put("result"," fail");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json;charset=utf-8");
            PrintWriter out = null;
            out = response.getWriter();
            out.write(json.toString());
        }
    }

    /**
     * 获取图片 使用输出流输出字节码，可以使用< img>标签显示图片<br>
     *
     * @param filePath 图片地址
     * @param response
     */
    @ApiOperation(value = "图片预览",notes = "输入图片地址返回图片流")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "filePath", value = "图片地址", required = true, dataType = "string"),
    })
    @GetMapping("/download/image")
    public void downloadImage(String filePath, HttpServletResponse response) throws Exception {

        OutputStream os = null;
        filePath = toLocal(filePath);
        // 文件名
        String contentType = this.EXT_MAPS.get(filePath.substring(filePath.lastIndexOf(".") + 1));
        InputStream is = null;
        try {
            // 下载
            byte[] fileByte = fastDFSClientComponent.download(filePath);

            if (response != null) {
                os = response.getOutputStream();
                // 设置响应头
                if (StringUtils.isNotBlank(contentType)) {
                    // 文件编码 处理文件名中的 '+'、' ' 特殊字符
                    String encoderName = URLEncoder.encode(filePath.substring(filePath.lastIndexOf("/")), "UTF-8").replace("+", "%20").replace("%2B", "+");
                    //response.setHeader("Content-Disposition", "attachment;filename=\"" + encoderName + "\"");
                    response.setContentType(contentType + ";charset=UTF-8");
                    response.setHeader("Accept-Ranges", "bytes");
                }
            }
            is = new ByteArrayInputStream(fileByte);
            byte[] buffer = new byte[1024 * 5];
            int len = 0;
            while ((len = is.read(buffer)) > 0) {
                os.write(buffer, 0, len);
            }
            os.flush();
        } catch (Exception e) {
            log.error("[查看文件]-错误:{},文件地址:{}", e.getMessage(), filePath);
        } finally {
            // 关闭流
            try {
                if(is != null){
                    is.close();
                }
                if(os != null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String toLocal(String path) {
        if (StringUtils.isNotBlank(path)) {
            path = path.replaceAll("\\\\", SEPARATOR);

            if (path.contains(POINT)) {
                String pre = path.substring(0, path.lastIndexOf(POINT) + 1);
                String suffix = path.substring(path.lastIndexOf(POINT) + 1).toLowerCase();
                path = pre + suffix;
            }
        }
        return path;
    }

}
